import 'dart:convert';

import 'package:http/http.dart' as http;

import '../common/test_page.dart';

class RequestTestPage extends TestPage {
  RequestTestPage(super.title) {
    group('#contentLength', () {
      test('http.Request(super.method, super.url)..bodyBytes根据Bytes类型的内容计算长度', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))..bodyBytes = [1, 2, 3, 4, 5];
        expect(request.contentLength, 5);
        request.bodyBytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        expect(request.contentLength, 10);
      });

      test('http.Request(super.method, super.url)..body根据内容计算长度', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))..body = 'hello';
        expect(request.contentLength, 5);
        request.body = 'hello, world';
        expect(request.contentLength, 12);
      });

      test('测试http.Request(super.method, super.url)不是直接可变的', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'));
        expect(() => request.contentLength = 50, '');
      });
    });

    group('#encoding', () {
      test('测试http.Request(super.method, super.url)默认编码', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'));
        expect(request.encoding.name, utf8.name);
      });

      test('测试http.Request(super.method, super.url)..encoding设置', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))..encoding = latin1;
        expect(request.encoding.name, latin1.name);
      });

      test('测试http.Request(super.method, super.url).header基于内容类型字符集', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'));
        request.headers['Content-Type'] = 'text/plain; charset=iso-8859-1';
        expect(request.encoding.name, latin1.name);
      });

      test('http.Request(super.method, super.url)如果内容类型charset已设置和未设置，则保持默认值',
              () {
            var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))
              ..encoding = latin1
              ..headers['Content-Type'] = 'text/plain; charset=utf-8';
            expect(request.encoding.name, utf8.name);

            request.headers.remove('Content-Type');
            expect(request.encoding.name, latin1.name);
          });

      test('测试http.Request(super.method, super.url)内容类型未知报错', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'));
        request.headers['Content-Type'] =
        'text/plain; charset=not-a-real-charset';
        expect(() => request.encoding, '');
      });
    });

    group('#bodyBytes', () {
      test('测试http.Request(super.method, super.url).bodyBytes默认值', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'));
        expect(request.bodyBytes, 'isEmpty');
      });

      test('测试bodyBytes设置值情况', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))
          ..bodyBytes = [104, 101, 108, 108, 111];
        expect(request.bodyBytes, [104, 101, 108, 108, 111]);
      });

      test('测试http.Request(super.method, super.url)..body发生变化时的情况', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))..body = 'hello';
        expect(request.bodyBytes, [104, 101, 108, 108, 111]);
      });
    });

    group('#body', () {
      test('测试http.Request(super.method, super.url).body默认值', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'));
        expect(request.body, 'isEmpty');
      });

      test('测试http.Request(super.method, super.url)..body设置值情况', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))..body = 'hello';
        expect(request.body, 'hello');
      });

      test('测试http.Request(super.method, super.url)..bodyBytes设置值情况', () {
        var request = http.Request('POST', Uri.parse('http://httpbin.org/post'))
          ..bodyBytes = [104, 101, 108, 108, 111];
        expect(request.body, 'hello');
      });

      test('测试http.Request(super.method, super.url)根据给定编码进行编码之后bodyBytes情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..encoding = latin1
          ..body = 'föøbãr';
        expect(request.bodyBytes, [102, 246, 248, 98, 227, 114]);
      });

      test('测试http.Request(super.method, super.url)根据给定编码进行解码之后body情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..encoding = latin1
          ..bodyBytes = [102, 246, 248, 98, 227, 114];
        expect(request.body, 'föøbãr');
      });
    });

    group('#bodyFields', () {
      test("测试http.Request(super.method, super.url).bodyFields不设置内容类型时读取情况", () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        expect(() => request.bodyFields, '');
      });

      test("测试http.Request(super.method, super.url).bodyFields读取错误的内容类型情况", () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'text/plain';
        expect(() => request.bodyFields, '');
      });

      test("测试http.Request(super.method, super.url).bodyFields设置错误的内容类型情况", () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'text/plain';
        expect(() => request.bodyFields = {}, '');
      });

      test('测试http.Request(super.method, super.url).bodyFields默认值', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        expect(request.bodyFields, 'isEmpty');
      });

      test('测试http.Request(super.method, super.url)..bodyFields在没有内容类型时设置情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..bodyFields = {'hello': 'world'};
        expect(request.bodyFields, {'hello': 'world'});
      });

      test('测试http.Request(super.method, super.url).bodyFields在body发生变化时的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        request.body = 'key%201=value&key+2=other%2bvalue';
        expect(request.bodyFields,
            {'key 1': 'value', 'key 2': 'other+value'});
      });

      test('测试http.Request(super.method, super.url).bodyFields根据给定编码进行编码的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..headers['Content-Type'] = 'application/x-www-form-urlencoded'
          ..encoding = latin1
          ..bodyFields = {'föø': 'bãr'};
        expect(request.body, 'f%F6%F8=b%E3r');
      });

      test('测试http.Request(super.method, super.url).bodyFields根据给定编码进行解码的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..headers['Content-Type'] = 'application/x-www-form-urlencoded'
          ..encoding = latin1
          ..body = 'f%F6%F8=b%E3r';
        expect(request.bodyFields, {'föø': 'bãr'});
      });
    });

    group('content-type header', () {
      test('测试http.Request(super.method, super.url).headers["Content-Type"]默认值', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        expect(request.headers['Content-Type'], 'isNull');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]仅设置编码的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))..encoding = latin1;
        expect(request.headers['Content-Type'], 'isNull');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]是否区分大小写', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['CoNtEnT-tYpE'] = 'application/json';
        expect(request.headers, 'content-type');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]设置了bodyFields时的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..bodyFields = {'hello': 'world'};
        expect(request.headers['Content-Type'],
            'application/x-www-form-urlencoded; charset=utf-8');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]设置了bodyFields和encoding的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..encoding = latin1
          ..bodyFields = {'hello': 'world'};
        expect(request.headers['Content-Type'],
            'application/x-www-form-urlencoded; charset=iso-8859-1');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]设置了body和encoding的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..encoding = latin1
          ..body = 'hello, world';
        expect(request.headers['Content-Type'],
            'text/plain; charset=iso-8859-1');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]设置body的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'application/json';
        request.body = '{"hello": "world"}';
        expect(request.headers['Content-Type'],
            'application/json; charset=utf-8');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]设置编码的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'application/json';
        request.encoding = latin1;
        expect(request.headers['Content-Type'],
            'application/json; charset=iso-8859-1');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"].encoding被显示编码覆盖的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'application/json; charset=utf-8';
        request.encoding = latin1;
        expect(request.headers['Content-Type'],
            'application/json; charset=iso-8859-1');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]无字符集通过设置bodyFields覆盖的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=iso-8859-1';
        request.bodyFields = {'hello': 'world'};
        expect(request.headers['Content-Type'],
            'application/x-www-form-urlencoded; charset=iso-8859-1');
      });

      test('测试http.Request(super.method, super.url).headers["Content-Type"]无字符集通过设置body覆盖的情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        request.headers['Content-Type'] = 'application/json; charset=iso-8859-1';
        request.body = '{"hello": "world"}';
        expect(request.headers['Content-Type'],
            'application/json; charset=iso-8859-1');
      });
    });

    group('#finalize', () {
      test('测试http.Request().finalize().bytesToString()返回情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))..body = 'Hello, world!';
        expect(request.finalize().bytesToString(),
            'Hello, world!');
      });

      test('测试http.Request().finalize().persistentConnection 正常和设置', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))..finalize();

        expect(request.persistentConnection, true);
        expect(() => request.persistentConnection = false, '');
      });

      test('测试http.Request().finalize().followRedirects 正常和设置', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))..finalize();

        expect(request.followRedirects, true);
        expect(() => request.followRedirects = false, '');
      });

      test('测试http.Request().finalize().maxRedirects 正常和设置', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))..finalize();

        expect(request.maxRedirects, 5);
        expect(() => request.maxRedirects = 10, '');
      });

      test('测试http.Request().finalize().encoding 正常和设置', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))..finalize();

        expect(request.encoding.name, utf8.name);
        expect(() => request.encoding = ascii, '');
      });

      test('测试http.Request().finalize().bodyBytes 正常和设置', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..bodyBytes = [1, 2, 3]
          ..finalize();

        expect(request.bodyBytes, [1, 2, 3]);
        expect(() => request.bodyBytes = [4, 5, 6], '');
      });

      test('测试http.Request().finalize().body 正常和设置', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..body = 'hello'
          ..finalize();

        expect(request.body, 'hello');
        expect(() => request.body = 'goodbye', '');
      });

      test('测试http.Request().finalize().bodyFields 正常和设置', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))
          ..bodyFields = {'hello': 'world'}
          ..finalize();

        expect(request.bodyFields, {'hello': 'world'});
        expect(() => request.bodyFields = {}, '');
      });

      test('测试http.Request().finalize()呼叫两次情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'))..finalize();
        expect(request.finalize, '');
      });
    });

    group('#toString()', () {
      test('测试http.Request(super.method, super.url).toString()情况', () {
        var request = http.Request('POST', Uri.parse('https://httpbin.org/post'));
        expect(request.toString(), 'POST ${Uri.parse('https://httpbin.org/post')}');
      });
    });

    group('#method', () {
      test('测试http.Request(super.method, super.url) 令牌super.method不正确的情况', () {
        expect(() => http.Request('LLAMA[0]', Uri.parse('https://httpbin.org/post')), '');
      });
    });
  }

}